/* eslint-disable no-param-reassign */
/* eslint-disable no-unused-expressions */
/**
 * @name Tree.tsx
 * @desc 组织架构左侧树
 * @author yangliu at 2020-02-07
 *
 */

import { Tree, Spin, Empty } from 'antd';
import * as React from 'react';
import { TreeType } from 'orgc-manage';
import { xhrGet, xhrPostJson } from '@/services/index';
import { MouseEvent } from 'react';
import { formatMessage } from '@/utils/i18n-transform';
import { transfer } from './common/util';
import Search from 'antd/lib/input/Search';

const { TreeNode } = Tree;
interface Api {
  url: string;
  params: any,
  type: string,
}
interface TreeProps {
  nodeInfo: TreeType;
  method?: 'POST' | 'GET';
  url: string;
  treeNodeClick: (data: TreeType) => any;
  changeTree: boolean;
  changeTreeData: () => void;
  parentIds?: any;
  initNull?: boolean;
  api?: Api,
  needSearch?: boolean;
}
interface TreeState {
  treeData: TreeType[];
  loading: boolean;
  expandedKeys: any[];
  autoExpandParent: boolean;
  searchValue: string;
}
export default class AsyncTree extends React.Component<TreeProps, TreeState> {
  dataList: any[] = [];

  constructor(props: TreeProps) {
    super(props);
    this.state = {
      treeData: [],
      loading: false,
      expandedKeys: [],
      autoExpandParent: true,
      searchValue: '',
    };
  }

  componentDidMount(): void {
    this.setState({ loading: true });
    this.getTreeData(this.props.nodeInfo).then(() => {
      this.setState({ loading: false });
    });
  }

  componentDidUpdate() {
    // 组织架构更新后刷新树

    const { nodeInfo, changeTree } = this.props;
    if (changeTree) {
      this.getTreeData(nodeInfo);
    }
  }

  componentWillReceiveProps(nextprops) {
    if (nextprops.url !== this.props.url) {
      this.queryTree(this.state.node)
    }
  }

  // 处理 onChange 事件
  onChange = (value: string) => {
    const { treeData } = this.state;
    const epKeys = this.dataList
      .map((item: any) => {
        if (item.title.indexOf(value) > -1) {
          return this.getParentKey(item.id, treeData);
        }
        return null;
      })
      .filter((item, i, self) => {
        console.log(item, self);
        return item && self.indexOf(item) === i;
      });

    this.setState({
      expandedKeys: epKeys,
      autoExpandParent: true,
      searchValue: value,
    });
  };

  getParentKey = (key: any, tree: any): any => {
    let parentKey;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some((item: any) => item.id === key)) {
          parentKey = node.id;
        } else if (this.getParentKey(key, node.children)) {
          parentKey = this.getParentKey(key, node.children);
        }
      }
    }
    return parentKey;
  };

  handleExpand = (expandedKeys: any) => {
    // setDefaultExpandedKeys(expandedKeys);
    this.setState({
      expandedKeys,
      autoExpandParent: false,
    });
  };

  getTreeData = async (params: TreeType) => {
    const { treeData } = this.state;
    const { url, api, method = 'GET' } = this.props;
    // whx add for 组织架构重构
    const xhrMethod = method === 'GET' ? xhrGet : xhrPostJson;
    await xhrMethod((api ? api?.url : url), params?.code === 'root' ? {} : { parentCode: params?.code }).then(
      (res: any) => {
        this.setState({
          treeData: this.setTreeData(treeData, transfer(res.result), params),
        });
        if (this.props.changeTree === true) {
          this.props.changeTreeData();
        }
      },
    );
  };

  // 处理treeData
  setTreeData = (data: TreeType[], children: TreeType[], params: TreeType): any => {
    if (params?.isRoot) {
      data = children;
    } else {
      data.map((item: TreeType) => {
        if (item.nodeType === params.nodeType && item.id === params.id) {
          // 操作后更新树的叶子节点
          children.length && children.length !== 0 ? (item.isLeaf = false) : (item.isLeaf = true);
          let nowChildren: any[] = [];
          children.forEach((ele: any) => {
            const originItem = item.children && item.children.filter(e => e.id === ele.id);
            if (originItem && originItem.length !== 0) {
              nowChildren = nowChildren.concat(originItem);
            } else {
              nowChildren.push(ele);
            }
          });
          item.children = nowChildren;
        } else if (item.children && item.children.length > 0) {
          this.setTreeData(item.children, children, params);
        }
      });
    }
    return data;
  };

  queryTree: any = (treeNode: MouseEvent<HTMLButtonElement> | any) =>
    new Promise(resolve => {
      if (treeNode.props.dataRef.childs) {
        resolve('');
        return;
      }
      if (treeNode.props.dataRef.nodeType !== 'JOB') {
        this.getTreeData(treeNode.props.dataRef).then(() => {
          resolve('');
        });
      }
    });

  /**
   * 树节点名称渲染
   * @param data
   */
  renderNodeTitle = (data: any) => {
    const { searchValue } = this.state;
    const index = data.name.indexOf(searchValue);
    const beforeStr = data.name.substr(0, index);
    const afterStr = data.name.substr(index + searchValue.length);
    return index > -1 ? (
      <span>
        {beforeStr}
        <span style={{ color: '#f50' }}>{searchValue}</span>
        {afterStr}
      </span>
    ) : (
      <span>{data.name}</span>
    );
  };

  renderTreeNodes = (data: TreeType[]) =>
    data.map(item => {
      const { initNull, parentIds } = this.props;
      if (initNull && (!parentIds || parentIds.length === 0)) {
        return Empty;
      }

      let rs = false;
      if (parentIds && parentIds.length > 0) {
        rs =
          parentIds.includes(item.code) || item.parentId === '0' || ['JOB'].includes(item.nodeType);
      }

      if (initNull && !rs) {
        return Empty;
      }

      const obj = {
        title: this.renderNodeTitle(item),
        key: item.id,
        props: {
          dataRef: item,
        },
        isLeaf: item.children && item.children.length ? false : item.isLeaf,
      };
      if (item.children) {
        return <TreeNode {...obj}>{this.renderTreeNodes(item.children)}</TreeNode>;
      }
      return <TreeNode {...obj} />;
    });

  treeClick = (node: string[], { selectedNodes }: any) => {
    if (selectedNodes && selectedNodes.length > 0) {
      this.setState({
        node: selectedNodes[0],
      })
      this.props.treeNodeClick(selectedNodes[0].props.dataRef);
    }
  };

  render() {
    const { treeData, loading, autoExpandParent, expandedKeys } = this.state;
    const { needSearch = true } = this.props;
    const obj: any = {
      showLine: true,
      loadData: this.queryTree,
      onSelect: this.treeClick,
      onExpand: this.handleExpand,
      expandedKeys,
      autoExpandParent,
    };
    this.dataList = [];
    const generateList = (data: any[]) => {
      for (let i = 0; i < data.length; i++) {
        const node = data[i];
        const { id } = node;
        this.dataList.push({ id, title: node.name });
        if (node.children) {
          generateList(node.children);
        }
      }
    };
    generateList(treeData);
    return (
      <Spin spinning={loading} tip={formatMessage({ id: 'loading' })}>
        {
          needSearch ? <Search style={{ marginBottom: 8 }} placeholder="输入名称" onSearch={this.onChange} /> : null
        }
        {treeData && treeData.length > 0 ? (
          <Tree {...obj}>{this.renderTreeNodes(treeData)}</Tree>
        ) : (
          <span>{loading ? '' : <Empty />}</span>
        )}
      </Spin>
    );
  }
}
